﻿using System;
using System.IO;
using System.Text;
using UtilZ.Dotnet.Ex.Communication.Net.DataTransfer.Base;
using UtilZ.Dotnet.Ex.Model;

namespace UtilZ.Dotnet.Ex.Communication.Net.DataTransfer.Udp
{
    /// <summary>
    /// UDP数据传输消息类型
    /// </summary>
    internal class UdpDataTransferMessageTypes
    {
        /// <summary>
        /// 发送消息
        /// </summary>
        public const byte SEND = 1;

        /// <summary>
        /// 确认消息
        /// </summary>
        public const byte ACK = 2;

        /// <summary>
        /// 请求消息
        /// </summary>
        public const byte REQ = 3;

        /// <summary>
        /// 响应消息
        /// </summary>
        public const byte RES = 4;

        /// <summary>
        /// 取消发送
        /// </summary>
        public const byte CANCELL = 5;
    }



    internal abstract class UdpDataTransferMessageAbs : DataTransferMesseageBaseAbs
    {

        public UdpDataTransferMessageAbs(byte messageType)
            : base(messageType)
        {

        }

    }

    internal class UdpSendMessage : UdpDataTransferMessageAbs
    {
        /****************************************************************************************************
         * 字段                 数据类型      大小            描述
         * 包头...
         * 
         * 发送资源数据长度     Int64         8               单位:byte
         * 超时时长             Int64         8               单位:毫秒.小于等于0表示无限,禁用超时机制
         * 发送优先级           byte          1               
         * UDP数据发送缓存大小  Int32         4               该值为发送方udp发送缓存大小        
         * 资源类型             byte          1               内存数据/文件的
         * 
         * 文件名称长度         Int16         2               当资源类型是文件时文件名的utf-8数据长度,非文件时为0
         * 文件名称             byte[]        文件名称长度
         * 资源数据长度         Int32         4               小于设置的UDP发送缓存大小时有效,大于时该值为0)
         * 资源数据             byte[]        资源数据长度    
         ****************************************************************************************************/


        private Int64 _sourceDataLength = 0L;
        /// <summary>
        /// 资源数据长度
        /// </summary>
        public Int64 SourceDataLength
        {
            get { return this._sourceDataLength; }
            set { this._sourceDataLength = value; }
        }

        private Int64 _millisecondsTimeout = 0L;
        /// <summary>
        /// 超时时长,单位:毫秒.小于等于0表示无限,禁用超时机制
        /// </summary>
        public Int64 MillisecondsTimeout
        {
            get { return this._millisecondsTimeout; }
            set { this._millisecondsTimeout = value; }
        }

        private byte _priorityLevel;
        /// <summary>
        /// 发送优先级
        /// </summary>
        public byte PriorityLevel
        {
            get { return this._priorityLevel; }
            set { this._priorityLevel = value; }
        }

        private Int32 _udpSendBufferLength = 0;
        /// <summary>
        /// UDP数据发送缓存大小
        /// </summary>
        public Int32 UdpSendBufferLength
        {
            get { return this._udpSendBufferLength; }
            set { this._udpSendBufferLength = value; }
        }

        private byte _sourceType = DataTransferRIDTypeConstant.MEMORY;
        /// <summary>
        /// 资源类型
        /// </summary>
        public byte SourceType
        {
            get { return this._sourceType; }
            set { this._sourceType = value; }
        }





        private string _sourceFileName = null;
        /// <summary>
        /// 文件名称
        /// </summary>
        public string SourceFileName
        {
            get { return this._sourceFileName; }
            set { this._sourceFileName = value; }
        }





        private byte[] _attatchDataBuffer = null;
        private DataSpan<byte> _attatchData = null;
        /// <summary>
        /// 资源附加数据
        /// </summary>
        public DataSpan<byte> AttatchData
        {
            get { return this._attatchData; }
            set { this._attatchData = value; }
        }



        public UdpSendMessage()
            : base(UdpDataTransferMessageTypes.SEND)
        {

        }







        /// <summary>
        /// 获取消息数据长度,不包含头
        /// </summary>
        /// <returns>消息数据长度</returns>
        protected override long GetMessageDataLength()
        {
            if (this._sourceType == DataTransferRIDTypeConstant.FILE)
            {
                if (this._attatchData == null || this._attatchData.Length == 0)
                {
                    return 28 + Encoding.UTF8.GetByteCount(this._sourceFileName);
                }
                else
                {
                    return 24 + Encoding.UTF8.GetByteCount(this._sourceFileName) + this._attatchData.Length;
                }
            }
            else
            {
                if (this._attatchData == null || this._attatchData.Length == 0)
                {
                    return 28;
                }
                else
                {
                    return 28 + this._attatchData.Length;
                }
            }
        }

        /// <summary>
        /// 写消息数据
        /// </summary>
        /// <param name="bufferData">目标数据</param>
        /// <param name="writer"></param>
        /// <exception cref="NotImplementedException"></exception>
        protected override void WriteMessageData(BufferData bufferData, BinaryWriter writer)
        {
            writer.Write(this._sourceDataLength);//发送资源数据长度
            writer.Write(this._millisecondsTimeout);//超时时长
            writer.Write(this._priorityLevel);//发送优先级
            writer.Write(this._udpSendBufferLength);//UDP数据发送缓存大小
            writer.Write(this._sourceType);//资源类型

            if (this._sourceType == DataTransferRIDTypeConstant.FILE)
            {
                byte[] nameBuffer = Encoding.UTF8.GetBytes(this._sourceFileName);
                writer.Write((short)nameBuffer.Length);//文件名称长度
                writer.Write(nameBuffer);//文件名称
            }
            else
            {
                writer.Write((short)0);//文件名称长度
            }

            if (this._attatchData != null && this._attatchData.Length > 0)
            {
                writer.Write(this._attatchData.Length);//资源数据长度
                writer.Write(this._attatchData.Buffer, this._attatchData.Offset, this._attatchData.Length);//资源数据
            }
            else
            {
                writer.Write(0);//资源数据长度
            }
        }

        /// <summary>
        /// 读取数据
        /// </summary>
        /// <param name="sourceData">原始数据</param>
        /// <param name="reader">数据读取器</param>
        /// <exception cref="NotImplementedException"></exception>
        protected override void ReadMessageData(BufferData sourceData, BinaryReader reader)
        {
            this._sourceDataLength = reader.ReadInt64();//发送资源数据长度
            this._millisecondsTimeout = reader.ReadInt64();//超时时长
            this._priorityLevel = reader.ReadByte();//发送优先级
            this._udpSendBufferLength = reader.ReadInt32();//UDP数据发送缓存大小
            this._sourceType = reader.ReadByte();//资源类型

            short nameLength = reader.ReadInt16();//文件名称长度
            if (nameLength > 0)
            {
                this._sourceFileName = Encoding.UTF8.GetString(sourceData.Bytes, (int)(sourceData.Offset + reader.BaseStream.Position), nameLength);//文件名称
                reader.BaseStream.Position += nameLength;
            }
            else
            {
                this._sourceFileName = null;
            }

            int resourceDataLength = reader.ReadInt32();//资源数据长度
            if (resourceDataLength > 0)
            {
                if (this._attatchDataBuffer == null || this._attatchDataBuffer.Length < resourceDataLength)
                {
                    this._attatchDataBuffer = new byte[resourceDataLength];
                    this._attatchData = new DataSpan<byte>(this._attatchDataBuffer);
                }
                reader.Read(this._attatchDataBuffer, 0, resourceDataLength);//携带的资源数据
                this._attatchData.Update(0, resourceDataLength);
            }
            else
            {
                if (this._attatchData != null)
                {
                    this._attatchData.Update(0, 0);
                }
            }
        }


    }

    internal class UdpAckMessage : UdpDataTransferMessageAbs
    {
        /****************************************************************************************************
         * 字段                 数据类型      大小            描述
         * 包头...
         * 
         * 发送结果             byte          1               0:收到;1:完成;2:失败;3:取消
         ****************************************************************************************************/

        public const byte RECEIVED = 0;

        public const byte COMPLETED = 1;

        public const byte FAIL = 2;

        public const byte CANCELL = 3;



        private byte _result = 0;

        /// <summary>
        /// 确认结果
        /// </summary>
        public byte Result
        {
            get { return this._result; }
            set { this._result = value; }
        }


        public UdpAckMessage()
           : base(UdpDataTransferMessageTypes.ACK)
        {

        }



        /// <summary>
        /// 获取消息数据长度,不包含头
        /// </summary>
        /// <returns>消息数据长度</returns>
        protected override long GetMessageDataLength()
        {
            return 1;
        }

        /// <summary>
        /// 写消息数据
        /// </summary>
        /// <param name="bufferData">目标数据</param>
        /// <param name="writer"></param>
        /// <exception cref="NotImplementedException"></exception>
        protected override void WriteMessageData(BufferData bufferData, BinaryWriter writer)
        {
            writer.Write(this._result);
        }

        /// <summary>
        /// 读取数据
        /// </summary>
        /// <param name="sourceData">原始数据</param>
        /// <param name="reader">数据读取器</param>
        /// <exception cref="NotImplementedException"></exception>
        protected override void ReadMessageData(BufferData sourceData, BinaryReader reader)
        {
            this._result = reader.ReadByte();
        }
    }


    /// <summary>
    /// 取消发送消息
    /// </summary>
    internal class UdpTransferCancellMesage : UdpDataTransferMessageAbs
    {
        public UdpTransferCancellMesage()
            : base(UdpDataTransferMessageTypes.CANCELL)
        {

        }

        /// <summary>
        /// 获取消息数据长度,不包含头
        /// </summary>
        /// <returns>消息数据长度</returns>
        protected override long GetMessageDataLength()
        {
            return 0;
        }

        /// <summary>
        /// 写消息数据
        /// </summary>
        /// <param name="bufferData">目标数据</param>
        /// <param name="writer"></param>
        /// <exception cref="NotImplementedException"></exception>
        protected override void WriteMessageData(BufferData bufferData, BinaryWriter writer)
        {

        }

        /// <summary>
        /// 读取数据
        /// </summary>
        /// <param name="sourceData">原始数据</param>
        /// <param name="reader">数据读取器</param>
        /// <exception cref="NotImplementedException"></exception>
        protected override void ReadMessageData(BufferData sourceData, BinaryReader reader)
        {

        }
    }


    internal class UdpRequestMessage : UdpDataTransferMessageAbs
    {
        /****************************************************************************************************
         * 字段                 数据类型      大小            描述
         * 包头...
         * 
         * 请求数据起始位置     Int64         8               单位:byte
         * 请求数据长度         Int32         4               单位:byte
         ****************************************************************************************************/


        private long _position = 0L;
        /// <summary>
        /// 请求数据起始位置
        /// </summary>
        public long Position
        {
            get { return this._position; }
            set { this._position = value; }
        }

        private int _length = 0;
        /// <summary>
        /// 请求数据长度
        /// </summary>
        public int Length
        {
            get { return this._length; }
            set { this._length = value; }
        }



        public UdpRequestMessage()
          : base(UdpDataTransferMessageTypes.REQ)
        {

        }



        /// <summary>
        /// 获取消息数据长度,不包含头
        /// </summary>
        /// <returns>消息数据长度</returns>
        protected override long GetMessageDataLength()
        {
            return 12;
        }

        /// <summary>
        /// 写消息数据
        /// </summary>
        /// <param name="bufferData">目标数据</param>
        /// <param name="writer"></param>
        /// <exception cref="NotImplementedException"></exception>
        protected override void WriteMessageData(BufferData bufferData, BinaryWriter writer)
        {
            writer.Write(this._position);
            writer.Write(this._length);
        }

        /// <summary>
        /// 读取数据
        /// </summary>
        /// <param name="sourceData">原始数据</param>
        /// <param name="reader">数据读取器</param>
        /// <exception cref="NotImplementedException"></exception>
        protected override void ReadMessageData(BufferData sourceData, BinaryReader reader)
        {
            this._position = reader.ReadInt64();
            this._length = reader.ReadInt32();
        }

    }

    internal class UdpResponsseMesage : UdpDataTransferMessageAbs
    {
        /****************************************************************************************************
         * 字段                 数据类型      大小            描述
         * 包头...
         * 
         * 请求数据起始位置     Int64         8               单位:byte
         * 请求数据长度         Int32         4               单位:byte
         * 请求数据             byte[]        请求数据长度    单位:byte
         ****************************************************************************************************/


        private long _position = 0L;
        /// <summary>
        /// 请求数据起始位置
        /// </summary>
        public long Position
        {
            get { return this._position; }
            set { this._position = value; }
        }

        private int _length = 0;
        /// <summary>
        /// 请求数据长度
        /// </summary>
        public int Length
        {
            get { return this._length; }
            set { this._length = value; }
        }


        private byte[] _data = null;
        /// <summary>
        /// 请求数据
        /// </summary>
        public byte[] Data
        {
            get { return this._data; }
            set { this._data = value; }
        }

        public UdpResponsseMesage()
          : base(UdpDataTransferMessageTypes.RES)
        {

        }

        /// <summary>
        /// 获取消息数据长度,不包含头
        /// </summary>
        /// <returns>消息数据长度</returns>
        protected override long GetMessageDataLength()
        {
            return 12 + this._length;
        }

        /// <summary>
        /// 写消息数据
        /// </summary>
        /// <param name="bufferData">目标数据</param>
        /// <param name="writer"></param>
        /// <exception cref="NotImplementedException"></exception>
        protected override void WriteMessageData(BufferData bufferData, BinaryWriter writer)
        {
            writer.Write(this._position);
            writer.Write(this._length);
            if (this._length > 0)
            {
                writer.Write(this._data, 0, this._length);
            }
        }

        /// <summary>
        /// 读取数据
        /// </summary>
        /// <param name="sourceData">原始数据</param>
        /// <param name="reader">数据读取器</param>
        /// <exception cref="NotImplementedException"></exception>
        protected override void ReadMessageData(BufferData sourceData, BinaryReader reader)
        {
            this._position = reader.ReadInt64();
            this._length = reader.ReadInt32();

            if (this._length > 0)
            {
                if (this._data == null || this._data.Length < this._length)
                {
                    this._data = new byte[this._length];
                }
                reader.Read(this._data, 0, this._length);
            }
        }
    }

}
